﻿using DapperLinq;
using ElasticSearchTest;
using JiebaNet.Segmenter;
using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommTest
{
    public class SyncElasticsearchData
    {
        readonly JiebaSegmenter Seg = new JiebaSegmenter();
        private readonly KeywordEsService _keywordEsService;
        private readonly CdnLogEsService _cdnLogEsService;

        //基础词库 城市, 城区, 学校名称/标签, 课程品牌
        SchoolRepository schoolRepository = new SchoolRepository();
        CourseRepository courseRepository = new CourseRepository();
        CommentRepository commentRepository = new CommentRepository();
        QuestionRepository questionRepository = new QuestionRepository();

        public SyncElasticsearchData(KeywordEsService keywordEsService, CdnLogEsService cdnLogEsService = null)
        {
            _keywordEsService = keywordEsService;
            _cdnLogEsService = cdnLogEsService;
        }

        public async Task Test()
        {
            SchoolRepository schoolRepository = new SchoolRepository();
            CourseRepository courseRepository = new CourseRepository();

            var r1 = this.Seg.Cut("TOI头脑风暴逻辑思维训练迷宫儿童桌面游戏玩具");
            var r2 = this.Seg.CutForSearch("TOI头脑风暴逻辑思维训练迷宫儿童桌面游戏玩具");

            IEnumerable<string> data = Enumerable.Empty<string>();
            data = await schoolRepository.GetNames(1, 10);
            var result = Seg.CutInParallel(data, cutAll: false).ToList();

            var data2 = await courseRepository.GetNames(1, 1000);
            var result2 = Seg.CutInParallel(data2).ToList();
            var result22 = Seg.CutForSearchInParallel(data2).ToList();

            SaveTxt(data, "学校名称.txt");
        }

        public async Task SyncCdnLogs() {

            var data = ReadText.GetCdnLogs();
            await _cdnLogEsService.AddBatchAsync(data);
        }

        public async Task Sync()
        {
            //await SyncCdnLogs();
            return;
            var sString = FormatString("阿斯頓煩煩煩");
            //await Test();
            //await HandlePushEs(new List<string>() { null });

            var size = 10000000;

            //1.保留原词
            //IEnumerable<string> keepSourceKeywords = new List<string>();
            //school
            //IEnumerable<string> schoolNames = await schoolRepository.GetNames(1, size);
            //keepSourceKeywords = keepSourceKeywords.Concat(schoolNames);

            var historyKeywords = ReadText.GetKeywordByHistory()
                                        .Where(s => s.TotalCount > 10) //频次超过10次
                                        .Select(s => s.SearchWord);
            //var tKeyword = historyKeywords.Where(s => s != null &&s.Contains("學")).ToList();
            //keepSourceKeywords = keepSourceKeywords.Concat(historyKeywords);

            //await HandlePushEs(keepSourceKeywords, keepSource: true);




            //2.不保留原词
            //IEnumerable<string> keywords = new List<string>();
            //var commentNames = await commentRepository.GetNames(1, size);
            //keywords = keywords.Concat(commentNames);

            //var questionNames = await questionRepository.GetNames(1, size);
            //keywords = keywords.Concat(questionNames);

            //var courseNames = await courseRepository.GetNames(1, size);
            //keywords = keywords.Concat(courseNames);
            //await HandlePushEs(keywords);
        }

        public async Task HandlePushEs(IEnumerable<string> strs, bool keepSource = false)
        {
            if (!strs.Any())
            {
                return;
            }

            //var result = seg.CutInParallel(data, cutAll: false).ToList();
            var cutStrs = Seg.CutForSearchInParallel(strs.Where(s => s != null));
            var filterStrs = keepSource ? Filter(cutStrs.Append(strs)) : Filter(cutStrs);
            var test = filterStrs.ToList();
            await _keywordEsService.AddBatchAsync(filterStrs);
        }

        public static bool Predicate(string str)
        {
            if (str == null)
            {
                return false;
            }

            return str.Length > 1;
        }
        public static string FormatString(string str)
        {
            if (str == null)
            {
                return string.Empty;
            }
            //移除纯英文数字特殊符号
            if (str.Where(c => IsAsc(c)).Count() == str.Length)
            {
                return string.Empty;
            }

            //去除两端空
            str = str.Trim();

            //去除标点
            //去除生僻词


            //转简体
            str = T2S(str);
            return str;
        }

        public static bool IsAsc(char c)
        {
            int acs = c;
            return acs >= 0 && acs < 128;
        }


        public static string T2S(string tString)
        {
            return ChineseConverter.Convert(tString, ChineseConversionDirection.TraditionalToSimplified);

            //only .netframework
            //return Microsoft.VisualBasic.Strings.StrConv(tString, Microsoft.VisualBasic.VbStrConv.SimplifiedChinese, 0);
        }

        public static IEnumerable<string> Filter(IEnumerable<string> strs)
        {
            return strs.AsParallel()
                .Select(s => FormatString(s))
                .Where(Predicate)
                .Distinct();
        }

        public static IEnumerable<string> Filter(IEnumerable<IEnumerable<string>> strs)
        {
            return strs.AsParallel()
                .SelectMany(list => list.Select(s => FormatString(s)))
                .Where(Predicate)
                .Distinct();
        }

        private static void SaveTxt(IEnumerable<string> keywords, string fileName)
        {
            using var inputStream = File.Create(fileName);
            foreach (var key in keywords)
            {
                var keyBytes = Encoding.UTF8.GetBytes(key + "\r\n");
                inputStream.Write(keyBytes);
            }
            inputStream.Flush();
            inputStream.Close();
        }
    }
}
